package etes;

import java.util.ArrayList;
import java.util.TreeMap;

import etes.Order;


public class OrderBook {

	private String instrumentName;
	private Integer bidPriority;
	private Integer AskPriority;
	private TreeMap<String, Order> bidOrderIDMap;
	private TreeMap<String, Order> askOrderIDMap;
	private TreeMap<String, Order> deleteOrderIDMap;
	private TreeMap<String, Order> offTradeIDMap;
	private TreeMap<String, Order> tradeIDMap;
	private TreeMap<String, Order> amendIDMap;
	private TreeMap<String, Order> cancelTradeIDMap;
	private TreeMap<Double, TreeMap<Integer, String>> orderedBids;
	private TreeMap<Double, TreeMap<Integer, String>> orderedAsks;

	public OrderBook() {
		this.bidPriority = 1;
		this.AskPriority = 1;


		this.bidOrderIDMap 		= new TreeMap<String, Order>();
		this.askOrderIDMap 		= new TreeMap<String, Order>();
		this.offTradeIDMap 		= new TreeMap<String, Order>();
		this.tradeIDMap 		= new TreeMap<String, Order>();
		this.amendIDMap 		= new TreeMap<String, Order>();
		this.cancelTradeIDMap 	= new TreeMap<String, Order>();
		this.deleteOrderIDMap	= new TreeMap<String, Order>();
		this.orderedBids 		= new TreeMap<Double, TreeMap<Integer, String>>();
		this.orderedAsks 		= new TreeMap<Double, TreeMap<Integer, String>>();
		
	}
	
	public void out() {
		/* we know that bidpriority and askpriority are equal to n+1 (where n is the number of bids/asks respectively)
		 * as it is initalised to 0 and incremented with each corresponding order that is entered into the book.
		 * We can use these as indices when outputting an orderbook. */
		
		Integer i = 0, j = 0, added = 0;
		ArrayList<String> orderedBidIDs = new ArrayList<String>();
		ArrayList<String> orderedAskIDs = new ArrayList<String>();

		
		for (Double d : orderedBids.keySet()) {
			added += orderedBids.get(d).values().size();
			System.out.println("adding " + orderedBids.get(d).values().size() + " IDs (bids: " + added + ") ");
			orderedBidIDs.addAll(orderedBids.get(d).values());
		}
		
		for (Double d : orderedAsks.descendingKeySet()) {
			for (Integer priority : orderedAsks.get(d).descendingKeySet()) {
				orderedAskIDs.add(orderedAsks.get(d).get(priority));
			}
		}
		
		/*for (TreeMap<Integer, String> t : orderedAsks.values()) {
			orderedAskIDs.addAll(t.values());
		}*/
		
		System.out.println("orderbook: " + orderedBids.size() + " (" + this.bidPriority + ") bids and " + orderedAsks.size() + " (" + this.AskPriority + ") asks");
		
		try
		{
			System.out.println();
			System.out.println("------------------------------------------- " + this.instrumentName + " Order Book -------------------------------------------");
			System.out.println("        Bid ID        |    Volume  |    Price   |--|    Price   |    Volume  |        Ask ID         ");
			System.out.println("------------------------------------------------------------------------------------------------------");
			while (i < this.bidPriority || j < this.AskPriority) {
	
				if (i < this.bidPriority && !bidOrderIDMap.isEmpty()) {
					if (bidOrderIDMap.containsKey(orderedBidIDs.get(i))) {
						bidOrderIDMap.get(orderedBidIDs.get(i)).quickPrintOrder();
						i++;
					} else {
						System.out.print("                                               ");
					}
				}
				else {
					System.out.print("                                               ");
				}
				
				System.out.print(" |--| ");
				
				if (j < this.AskPriority && !askOrderIDMap.isEmpty()) {
					askOrderIDMap.get(orderedAskIDs.get(j)).quickPrintOrder();
					j++;
				}
				
				System.out.print("\n");
			}
		}
		catch (Exception e)
		{
			System.out.println("LOL SHIT: " + e.getMessage());
		}
	}
		
	public void printBids() {
		for (String s : bidOrderIDMap.keySet())
			bidOrderIDMap.get(s).printOrder();
	}
	public void printAsks() {
		for (String s : askOrderIDMap.keySet())
			askOrderIDMap.get(s).printOrder();
	}

	public Integer getBidPriority() {
		return bidPriority;
	}

	public void setBidPriority(Integer bidPriority) {
		this.bidPriority = bidPriority;
	}

	public Integer getAskPriority() {
		return AskPriority;
	}

	public void setAskPriority(Integer askPriority) {
		AskPriority = askPriority;
	}

	public TreeMap<String, Order> getAskOrderIDMap() {
		return askOrderIDMap;
	}

	public void setAskOrderIDMap(TreeMap<String, Order> askOrderIDMap) {
		this.askOrderIDMap = askOrderIDMap;
	}

	public TreeMap<String, Order> getBidOrderIDMap() {
		return bidOrderIDMap;
	}

	public void setBidOrderIDMap(TreeMap<String, Order> bidOrderIDMap) {
		this.bidOrderIDMap = bidOrderIDMap;
	}

	public TreeMap<Double, TreeMap<Integer, String>> getOrderedAsks() {
		return orderedAsks;
	}

	public void setOrderedAsks(TreeMap<Double, TreeMap<Integer, String>> orderedAsks) {
		this.orderedAsks = orderedAsks;
	}

	public TreeMap<Double, TreeMap<Integer, String>> getOrderedBids() {
		return orderedBids;
	}

	public void setOrderedBids(TreeMap<Double, TreeMap<Integer, String>> orderedBids) {
		this.orderedBids = orderedBids;
	}
	
	
	public TreeMap<String, Order> getCancelTradeIDMap() {
		return cancelTradeIDMap;
	}

	public void setCancelTradeIDMap(TreeMap<String, Order> cancelTradeIDMap) {
		this.cancelTradeIDMap = cancelTradeIDMap;
	}

	public TreeMap<String, Order> getDeleteOrderIDMap() {
		return deleteOrderIDMap;
	}

	public void setDeleteOrderIDMap(TreeMap<String, Order> deleteOrderIDMap) {
		this.deleteOrderIDMap = deleteOrderIDMap;
	}

	public TreeMap<String, Order> getOffTradeIDMap() {
		return offTradeIDMap;
	}

	public void setOffTradeIDMap(TreeMap<String, Order> offTradeIDMap) {
		this.offTradeIDMap = offTradeIDMap;
	}

	public TreeMap<String, Order> getAmendIDMap() {
		return amendIDMap;
	}

	public void setAmendIDMap(TreeMap<String, Order> amendIDMap) {
		this.amendIDMap = amendIDMap;
	}

	public TreeMap<String, Order> getTradeIDMap() {
		return tradeIDMap;
	}

	public void setTradeIDMap(TreeMap<String, Order> tradeIDMap) {
		this.tradeIDMap = tradeIDMap;
	}

	public String getInstrumentName() {
		return instrumentName;
	}

	public void setInstrumentName(String instrumentName) {
		this.instrumentName = instrumentName;
	}
	
}
